package com.hancheng.commoncloud.framework.aop;

import cn.hutool.core.util.IdUtil;
import com.hancheng.commoncloud.framework.contant.Constants;
import com.hancheng.commoncloud.framework.util.NetworkUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 日志拦截器组件，在输出日志中加上trackId
 *
 * @author 金笛
 * @date 2022/1/23 12:40
 * @Description: 日志格式加上 %X{trackId}
 */
@Slf4j
@Setter
@Component
public class LogInterceptor extends HandlerInterceptorAdapter {
    /**
     * 需要打印的头部
     */
    private String[] headers = new String[]{Constants.AUTH_TOKEN};

    /**
     * 统计接口耗时
     */
    private final ThreadLocal<Long> REQUEST_TIME = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 开始时间
        REQUEST_TIME.set(System.currentTimeMillis());
        String trackId = IdUtil.simpleUUID().substring(0, 8);
        MDC.clear();
        MDC.put(Constants.MDC_REQUEST_ID, trackId);
        // 写入response,方便排查日志
        response.setHeader(Constants.MDC_REQUEST_ID, trackId);

        log.info("请求开始, ip: {}, method: {}, url: {}, header: {}, query: {}",
                NetworkUtils.getIpAddr(request), request.getMethod(), request.getRequestURI(),
                NetworkUtils.getHeaders(request, headers), request.getQueryString());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)
            throws Exception {
        // 请求结束处理
        long time = System.currentTimeMillis() - REQUEST_TIME.get();

        String data = String.valueOf(request.getAttribute("response"));
        log.info("请求结束, data: {}, time: {}ms", data, time);
        MDC.remove(Constants.MDC_REQUEST_ID);
        REQUEST_TIME.remove();
    }
}